﻿using Abp.Collections.Extensions;
using Abp.Domain.Repositories;
using Abp.Extensions;
using Camc.Quality.Bom;
using Camc.Quality.Bop;
using Camc.Quality.DataDictionary;
using Camc.Quality.Materials;
using Camc.Quality.Quality;
using Camc.Quality.RecordTable.FormClass;
using Camc.Quality.StoreManagement.StoragePut;
using Camc.Quality.TrepanningManager.BomNestingInterface;
using Camc.Quality.TrepanningManager.MatingManager;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

namespace Camc.Quality.TrepanningManager.PrintLabelManager
{
    public class PrintMatingLabelAppService : QualityAppServiceBase
    {
        private readonly IRepository<MaterialsContent, Guid> _materialsContentRepository;
        private readonly IBomAnalyseExportToExcel _bomAnalyseExportToExcel;
        private readonly IRepository<BomDesign, Guid> _bomDesignrepository;
        private readonly IRepository<TechniqueEntity, Guid> _techniqueEntityRepository;
        private readonly IRepository<BopNode, Guid> _bopNodeRepository;
        private readonly IRepository<ProcessesEntity, Guid> _processesEntityRepository;
        private readonly IRepository<WorkStepEntity, Guid> _workStepEntityRepository;
        private readonly IRepository<LoadPieceEntity, Guid> _loadPieceRepository;
        private readonly IRepository<MaterialsNode, Guid> _materialsNodeRepository;
        private readonly IRepository<Sys_Code, Guid> _sysCodeRepository;
        public readonly IRepository<StoreStock, Guid> _storeStockRepsitory;
        private readonly IRepository<BopDesc, Guid> _bopDescRepository;
        public PrintMatingLabelAppService(IRepository<MaterialsContent, Guid> materialsContentRepository, IBomAnalyseExportToExcel bomAnalyseExportToExcel, IRepository<TechniqueEntity, Guid> techniqueEntityRepository, IRepository<BopNode, Guid> bopNodeRepository, IRepository<ProcessesEntity, Guid> processesEntityRepository, IRepository<WorkStepEntity, Guid> workStepEntityRepository, IRepository<LoadPieceEntity, Guid> loadPieceRepository, IRepository<Sys_Code, Guid> sysCodeRepository, IRepository<StoreStock, Guid> storeStockRepsitory, IRepository<BopDesc, Guid> bopDescRepository, IRepository<MaterialsNode, Guid> materialsNodeRepository)
        {
            this._materialsContentRepository = materialsContentRepository;
            this._bomAnalyseExportToExcel = bomAnalyseExportToExcel;
            this._techniqueEntityRepository = techniqueEntityRepository;
            this._bopNodeRepository = bopNodeRepository;
            this._processesEntityRepository = processesEntityRepository;
            this._workStepEntityRepository = workStepEntityRepository;
            this._loadPieceRepository = loadPieceRepository;
            this._sysCodeRepository = sysCodeRepository;
            this._storeStockRepsitory = storeStockRepsitory;
            this._bopDescRepository = bopDescRepository;
            this._materialsNodeRepository = materialsNodeRepository;
        }
        /// <summary>
        /// 主表格显示 弃用
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<MatingTreeGridDto>> PrintMatingNodeDetails(PrintLabelEditDto printLabelEditDto)
        {
            if (printLabelEditDto.BTId != Guid.Empty)
            {
                List<MatingTreeGridDto> outputs = new List<MatingTreeGridDto>();
                var loadQuery = _loadPieceRepository.GetAll();
                int Level = 0;
                var bopNode = _bopNodeRepository.Get(printLabelEditDto.BTId);
                var techId = bopNode.TechniqueEntityId;
                List<Guid> bopGzxm = new List<Guid>();
                List<BopNode> bopNodeList = new List<BopNode>();
                if (techId == null)
                {
                    bopNodeList =
                       (from techniqueContent in _techniqueEntityRepository.GetAll().WhereIf(!printLabelEditDto.GCCode.IsNullOrWhiteSpace(), t => t.TechniqueNumber.StartsWith(printLabelEditDto.GCCode)).WhereIf(!printLabelEditDto.GCName.IsNullOrWhiteSpace(), t => t.TechniqueName.StartsWith(printLabelEditDto.GCName))
                       join bopNodeContent in _bopNodeRepository.GetAll().Where(t => t.ParentId == bopNode.Id && t.TechniqueEntityId != null)
                                  on techniqueContent.Id equals bopNodeContent.TechniqueEntityId
                       select bopNodeContent).ToList();
                    if (bopNodeList != null && bopNodeList.Count() > 0)
                    {
                        bopGzxm = bopNodeList.Select(t => t.TechniqueEntityId.Value).ToList();
                    }
                }
                else
                {
                    bopGzxm.Add(techId.Value);
                }
                if (bopGzxm != null)
                {
                    TechniqueEntity gclist = null;
                    foreach (Guid node in bopGzxm)
                    {
                            gclist = _techniqueEntityRepository.Get(node);
                        var proTemp = _processesEntityRepository.GetAll().Where(d => d.TechniqueEntityId == node).OrderBy(d => d.ProcessesSequence).ToList();
                        if (proTemp.Count > 0)
                        {
                            foreach (var item in proTemp)
                            {
                                MatingTreeGridDto mating = new MatingTreeGridDto();
                                var workIds = _workStepEntityRepository.GetAll().Where(d => d.ProcessesEntityId == item.Id).Select(d => d.Id);
                                if (workIds.Count() > 0)
                                {
                                    MatingEditParentData matingpd = new MatingEditParentData();
                                    matingpd.Code = "工序" + item.ProcessesSequence.ToString() + " ";
                                    matingpd.Name = item.ProcessesName;
                                    matingpd.Id = item.Id;
                                    matingpd.NodeLevel = 8;
                                    matingpd.JoinText = printLabelEditDto.Module + @"/" + printLabelEditDto.SendTime + @"/" + printLabelEditDto.XjName + @"/" + printLabelEditDto.BTName + @"/" +  gclist.TechniqueNumber + @"/"+ gclist.TechniqueName + @"/" + matingpd.Code;
                                    Level++;
                                    matingpd.LevelName = Level.ToString();
                                    mating.data = matingpd;
                                    //获取工序下的所有工步
                                    var workTemp = _workStepEntityRepository.GetAll().Where(d => d.ProcessesEntityId == item.Id).OrderBy(d => d.WorkStepNumber).ToList();
                                    if (workTemp.Count > 0)
                                    {
                                        MatingTreeGridDto matingTree = new MatingTreeGridDto();
                                        int childchildLevel = 0;
                                        //找出所有工步的id
                                        var workIdList = workTemp.Select(d => d.Id).ToList();
                                        //循环工步id
                                        for (int i = 0; i < workIdList.Count; i++)
                                        {
                                            MatingDetaillist detaillist = new MatingDetaillist();
                                            var work = workTemp.Where(d => d.Id == workIdList[i]).First();
                                            detaillist.data = new MatingEditChildData()
                                            {
                                                Id = work.Id,
                                                Code = "工步" + item.ProcessesSequence.ToString() + "-" + work.WorkStepNumber.ToString(),
                                                Name = work.WorkStepNumber.ToString(),
                                                LevelName = matingpd.LevelName + "." + (i + 1).ToString(),
                                                JoinText = printLabelEditDto.Module + @"/" + printLabelEditDto.SendTime + @"/" + printLabelEditDto.XjName + @"/" + printLabelEditDto.BTName + @"/" +  gclist.TechniqueNumber  + @"/" +  gclist.TechniqueName + @"/" + matingpd.Code+ @"/" + "工步" + item.ProcessesSequence.ToString() + "-" + work.WorkStepNumber.ToString()
                                            };
                                            mating.children.Add(detaillist);
                                            //根据每个工步id 过滤出装入件明细
                                        }
                                    }
                                }
                                outputs.Add(mating);
                            }
                        }
                    }
                }
                return outputs;
            }
            return new List<MatingTreeGridDto>();
            //else
            //{
            //    throw new Exception("传入数据有误!");
            //}
        }
        /// <summary>
        /// 根据型号和发次获取树结构
        /// </summary>
        /// <param name="model">型号</param>
        /// <param name="lotNo">发次</param>
        /// <returns></returns>
        public PrintLabelTreeDto GetPrintProductionDesigenTree(Guid? model, Guid? lotNo)
        {
            PrintLabelTreeDto output = new PrintLabelTreeDto();

            var bopDescTemp = _bopDescRepository.GetAll().Where(d => d.ModelId == model && d.LotNoId == lotNo).FirstOrDefault();
            if (bopDescTemp != null)
            {
                output.Id = bopDescTemp.Id;
                output.ParentId = Guid.Empty;
                output.NodeDrawingNo = bopDescTemp.DrawingNo;
                output.NodeName = bopDescTemp.ModelName;
                output.IsRelation = 0;
                output.NodeLevel = 0;
                LoadPrintChildNode(bopDescTemp.Id, output);
                return output;
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// 加载bop节点递归
        /// </summary>
        /// <param name="Id"></param>
        /// <param name="treeNodeDto"></param>
        private void LoadPrintChildNode(Guid Id, PrintLabelTreeDto treeNodeDto)
        {
            var bopNodeList = _bopNodeRepository.GetAll().Where(c => c.ParentId == Id).OrderBy(d => d.CreationTime);
            //var list = ObjectMapper.Map<List<BopNodeDto>>(bopNodeList);
            foreach (var item in bopNodeList)
            {
                PrintLabelTreeDto tree = new PrintLabelTreeDto();
                tree.Id = item.Id;
                tree.ParentId = item.ParentId;
                tree.NodeDrawingNo = item.NodeDrawingNo;
                tree.NodeName = item.NodeName;
                if (item.TechniqueEntityId == null)
                    tree.IsRelation = 0;
                else
                {
                    tree.IsRelation = 1;
                    var tech = _techniqueEntityRepository.GetAll().FirstOrDefault(d => d.Id == item.TechniqueEntityId.Value);
                    if (tech != null)
                    {

                        tree.OutboundStatusDesc = GetPrintEnumDesc(tech.OutboundState);
                    }
                    else
                    {
                        tree.OutboundStatusDesc = "";
                    }

                }

                tree.NodeLevel = item.NodeLevel;   //NodeLevel;
                tree.ParentCode = item.ParentCode;
                tree.NodeCode = item.NodeCode;
                tree.IsLeaf = item.IsLeaf;
                tree.IsExport = item.IsExport;
                //递归性质，函数内调用自身函数
                //NodeLevel++;
                LoadPrintChildNode(item.Id, tree);
                //NodeLevel--;
                //递归结束的终点条件
                treeNodeDto.Children.Add(tree);
            }
        }
        /// <summary>
        /// 懒加载获取工序工步树节点
        /// </summary>
        /// <param name="NodeId"></param>
        /// <returns></returns>
        public List<PrintLabelTreeDto> GetProductionPrintTechquine(Guid NodeId)
        {
            PrintLabelTreeDto output = new PrintLabelTreeDto();
            LoadPrintTechquine(NodeId, output);
            return output.Children;
        }
        /// <summary>
        /// 加载工步工序节点
        /// </summary>
        /// <param name="NodeId"></param>
        /// <param name="treeNodeDto"></param>
        private void LoadPrintTechquine(Guid NodeId, PrintLabelTreeDto treeNodeDto)
        {
            //获取节点信息的工艺规程编码
            var bomNode = _bopNodeRepository.FirstOrDefault(x => x.Id == NodeId);
            string processCode = bomNode.ProcessCode;
            //根据工艺规程编码获取工艺文件表Id,已关联文件
            var tech = _techniqueEntityRepository.FirstOrDefault(x => x.Id == bomNode.TechniqueEntityId);
            if (tech == null) return;
            Guid techId = tech.Id;
            //获取工序和工步的信息，并做相应的排序
            var processesList = _processesEntityRepository.GetAllIncluding(p => p.WorkStepEntities).Where(p => p.TechniqueEntityId == techId).OrderBy(n => n.ProcessesSequence).ToList();
            processesList.ToList().ForEach(q => q.WorkStepEntities = q.WorkStepEntities.OrderBy(r => r.WorkStepNumber).ToList());
            //循环遍历，往Node里面赋值
            foreach (var item in processesList)
            {
                var workIds = _workStepEntityRepository.GetAll().Where(d => d.ProcessesEntityId == item.Id).Select(d => d.Id);
                if (workIds.Count() > 0)
                {
                    PrintLabelTreeDto tree = new PrintLabelTreeDto();
                    tree.Id = item.Id;
                    tree.ParentId = NodeId;
                    tree.NodeDrawingNo = "工序" + item.ProcessesSequence.ToString() + " ";
                    tree.NodeName = item.ProcessesName;
                    tree.IsRelation = 0;
                    tree.NodeLevel = 8;
                    tree.OutboundStatusDesc = GetPrintEnumDesc(item.OutboundState);
                    treeNodeDto.Children.Add(tree);
                }
                //查询工步
                //foreach (var witem in item.WorkStepEntities)
                //{
                //    PrintLabelTreeDto wtree = new PrintLabelTreeDto();
                //    wtree.Id = witem.Id;
                //    wtree.ParentId = item.Id;
                //    wtree.NodeDrawingNo = "工步" + item.ProcessesSequence.ToString();// + "-"+ witem.WorkStepNumber.ToString();
                //    wtree.NodeName = witem.WorkStepNumber.ToString();//witem.WorkStepName  这个值数据库有问题
                //    wtree.IsRelation = 0;
                //    wtree.NodeLevel = 9;
                //    wtree.OutboundStatusDesc = GetPrintEnumDesc(witem.OutboundState);
                //    tree.Children.Add(wtree);
                //}
            }
        }
        /// <summary>
        /// 根据枚举获取枚举描述信息
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        private static string GetPrintEnumDesc(System.Enum parm)
        {
            FieldInfo enumInfo = parm.GetType().GetField(parm.ToString());
            if (enumInfo == null)
            {
                return "";
            }
            DescriptionAttribute[] enumAttributes
                = (DescriptionAttribute[])enumInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
            if (enumAttributes.Length > 0)
            {
                return enumAttributes[0].Description;
            }
            return parm.ToString();
        }
        public List<MatingEditParentData> DisplayPrintMatingNodeDetails(Guid id)
        {
            List<MatingEditParentData> outputs = new List<MatingEditParentData>();
            if (id != Guid.Empty)
            {
                int route = RouteType(id);
             
                var loadQuery = _loadPieceRepository.GetAll();
                int Level = 0;
                switch (route)
                {
                    case 1:
                    case 2:
                        var bopNodes = _bopNodeRepository.GetAll().Where(d => d.ParentId == id).OrderBy(d => d.CreationTime).ToList();
                        if (bopNodes.Count() > 0)
                        {
                            foreach (var item in bopNodes)
                            {
                                string matingName = "";
                                var techQuery = _bopNodeRepository.GetAll().Where(d => d.NodeCode.StartsWith(item.NodeCode) && d.BopDescId == item.BopDescId).Where(d => d.TechniqueEntityId != null).Select(d => d.TechniqueEntityId).ToList();
                                if (techQuery.Count > 0)
                                {
                                    
                                    MatingEditParentData temp = new MatingEditParentData();
                                    temp.Code = item.NodeDrawingNo;
                                    temp.Name = item.NodeName;
                                    temp.MatingStatusName = matingName;
                                    Level++;
                                    temp.LevelName = Level.ToString();
                                    outputs.Add(temp);
                                }
                            }
                        }
                        break;
                    case 3:
                        var bopNode = _bopNodeRepository.Get(id);
                        var coreGradeNode = _bopNodeRepository.GetAll().Where(d => d.NodeCode == bopNode.ParentCode.Substring(0, 3) && d.ParentId == bopNode.BopDescId).FirstOrDefault();//芯级名字
                        var bopDesc = _bopDescRepository.FirstOrDefault(t => t.Id == coreGradeNode.BopDescId);
                        var techId = bopNode.TechniqueEntityId;
                        var techName = _techniqueEntityRepository.FirstOrDefault(t => t.Id == bopNode.TechniqueEntityId);//工艺规程名字
                        List<LoadPieceEntity> loadPieceEntities = new List<LoadPieceEntity>();
                        var proTemp = _processesEntityRepository.GetAll().Where(d => d.TechniqueEntityId == techId).OrderBy(d => d.ProcessesSequence).ToList();
                        if (proTemp.Count > 0)
                        {
                            foreach (var item in proTemp)
                            {
                                string matingName = "";
                                var workIds = _workStepEntityRepository.GetAll().Where(d => d.ProcessesEntityId == item.Id).Select(d => d.Id);
                                if (workIds.Count() > 0)
                                {
                                    MatingEditParentData matingpd = new MatingEditParentData();
                                    matingpd.Code = "工序" + item.ProcessesSequence.ToString() + " ";
                                    matingpd.Name = item.ProcessesName;
                                    matingpd.Id = item.Id;
                                    matingpd.JoinText = "工序";
                                    matingpd.NodeLevel = 8;
                                    Level++;
                                    matingpd.MatingStatusName = matingName;
                                    matingpd.JoinText = bopDesc.Model + @"/" + bopDesc.LotNo + @"/" + coreGradeNode.NodeName+ @"/" + bopNode.NodeName + @"/" + techName.TechniqueNumber + @"/" + techName.TechniqueName + @"/" + matingpd.Code;
                                    matingpd.LevelName = Level.ToString();
                                    //找出所有的装入件
                                    var loadList = from cc in loadQuery
                                                   join mm in workIds on cc.WorkStepEntityId equals mm
                                                   select cc;
                                    var maping = ObjectMapper.Map<List<PrintLoadEntityDto>>(loadList).ToList();
                                    matingpd.printLoadEntityDtos.AddRange(maping);
                                    outputs.Add(matingpd);
                                }
                            }
                        }
                        break;
                    case 4:
                        var proceTemp = _processesEntityRepository.Get(id);
                        int numberCount = 0;
                        string xjcode = "";
                        string xjName = "";
                        //获取工序下的所有工步
                        var workTemp = _workStepEntityRepository.GetAll().Where(d => d.ProcessesEntityId == id).OrderBy(d => d.WorkStepNumber).ToList();
                        if (workTemp.Count > 0)
                        {
                                var workIdList = workTemp.Select(d => d.Id).ToList();
                                //找出预配套的数量R
                                List<MatingDetaillist> tempQuery = new List<MatingDetaillist>();

                                if (workIdList.Count() > 0)
                                {
                                        //循环工步id
                                        for (int i = 0; i < workIdList.Count; i++)
                                        {
                                            var work = workTemp.Where(d => d.Id == workIdList[i]).First();
                                            MatingEditParentData matingpd = new MatingEditParentData();
                                            //工步id
                                            matingpd.Id = work.Id;
                                            matingpd.Code = "工步" + proceTemp.ProcessesSequence.ToString() + "-" + work.WorkStepNumber.ToString();
                                            matingpd.Name = work.WorkStepNumber.ToString();
                                            matingpd.JoinText = "工步";
                                            matingpd.LevelName = (i + 1).ToString();
                                            var loadList = loadQuery.Where(t => t.WorkStepEntityId == workIdList[i]).ToList();
                                            var maping = ObjectMapper.Map<List<PrintLoadEntityDto>>(loadList).ToList();
                                            matingpd.printLoadEntityDtos.AddRange(maping);
                                            //matingpd.MatingStatusName = "缺料";
                                            //根据每个工步id 过滤出装入件明细
                                            outputs.Add(matingpd);
                                        }
                                }
                            }
                        break;
                    default:
                        break;
                }
                return outputs;
            }
            else
            {
                throw new Exception("传入数据有误!");
            }
        }
        /// <summary>
        /// 查找当前节点类型 1 任务-节点  2 节点-节点 3 节点-工序 4 工序-工步 5 工步
        /// </summary>
        /// <param name="ParentId"></param>
        /// <returns></returns>
        private int RouteType(Guid ParentId)
        {
            var bopDesc = _bopDescRepository.GetAll().Where(d => d.Id == ParentId).FirstOrDefault();
            if (bopDesc != null)
            {
                return 1;
            }
            var bopNode = _bopNodeRepository.GetAll().Where(d => d.Id == ParentId).FirstOrDefault();
            if (bopNode != null)
            {
                if (!string.IsNullOrEmpty(bopNode.ProcessCode))
                {
                    return 3;
                }
                else
                {
                    return 2;
                }
            }
            var processEntity = _processesEntityRepository.GetAll().Where(d => d.Id == ParentId).FirstOrDefault();
            if (processEntity != null)
            {
                return 4;
            }
            var workEntity = _workStepEntityRepository.GetAll().Where(d => d.Id == ParentId).FirstOrDefault();
            if (workEntity != null)
            {
                return 5;
            }
            return 0;
        }
    }
}
